import axios from "axios";
import { removeStore, getCookie, setCookie, removeCookie } from "@/libs/storage.js";
import { router } from "../router/index";
import { Message } from "view-design";
import { handleRefreshToken } from "../api/index";
import getUuidv4 from './uuid';
let msg = null;

// 统一请求路径前缀
export const commonUrl =
  process.env.NODE_ENV === "development"
    ? BASE.API_DEV.common
    : BASE.API_PROD.common;
export const managerUrl =
  process.env.NODE_ENV === "development"
    ? BASE.API_DEV.manager
    : BASE.API_PROD.manager;
export const communityUrl = 
  process.env.NODE_ENV === "development"
    ? BASE.API_DEV.community
    : BASE.API_PROD.community
// 文件上传接口
export const uploadFile = `${commonUrl}/common/common/upload/file`;


const service = axios.create({
  timeout: 30 * 1000,
  baseURL: managerUrl
});
var isRefreshToken = 0;
const refreshToken = getTokenDebounce();
service.interceptors.request.use(
  config => {
    if (config.method == "get") {
      config.params = {
        _t: Date.parse(new Date()) / 1000,
        ...config.params
      };
    }
    let uuid = getCookie("uuid");
    if (!uuid) {
      uuid = getUuidv4();
      setCookie('uuid', uuid);
    }
    config.headers["uuid"] = uuid;
    return config;
  },
  err => {
    if (msg) Message.destroy();
    msg = Message.error("请求超时");
    return Promise.reject(err);
  }
);

// http response 拦截器
service.interceptors.response.use(
  response => {
    const data = response.data;
    // 根据返回的code值来做不同的处理(和后端约定)
    if (!data.success && data.code == 99999) {
      return data;
    }
    if (!data.success && data.message) {
      if (msg) Message.destroy();
      msg = Message.error(data.message);
    }
    switch (data.code) {
      case 0:
      case 400:
        if (msg) Message.destroy();
        msg = Message.error(data.message || data.msg || "系统异常");
        break;
      case 20004:
      case 401:
        // 未登录 清除已登录状态
        removeStore("userInfoManager");
        removeCookie("accessToken");
        removeCookie("refreshToken");
        if (router.history.current.name != "login") {
          if (msg) Message.destroy();
          msg = Message.error(data.message || "登录失效，请重新登录");
          router.push("/login");
        }
        return data;
        break;
      case 500:
        // 系统异常
        if (msg) Message.destroy();
        msg = Message.error(data.message || "系统异常");
        break;
      default:
        return data;
    }
  },
  async error => {
    // 返回状态码不为200时候的错误处理
    if (error.response) {
      if (error.response.status === 401 || error.response.status === 403) {
        isRefreshToken++;
        if (isRefreshToken === 1) {
          refresh(error);
          isRefreshToken = 0;
        }
      } else if (error.response.status === 404) {
        // 避免刷新token报错
      }  else if (error.response.status === 405) {
        // 
      } else if (error.response.status == 400) {
        if (error.response.data.code == 20004) {
          if (msg) Message.destroy();
          msg = Message.error("登录已过期，请重新登录");
          router.push("/login");
        } else if (error.response.data.code == 20003) {
          isRefreshToken++;
          if (isRefreshToken === 1) {
            refresh(error);
            isRefreshToken = 0;
          }
        } else {
          if (msg) Message.destroy();
          msg = Message.error(error.response.data.message);
        }
      } else {
        // 其他错误处理
          if (msg) Message.destroy();
          msg = Message.error(error.response.data.message);
      }
    }
    /* router.push("/login") */
    return Promise.resolve(error);
  }
);

async function refresh(error) {
  const getTokenRes = await refreshToken();
  if (getTokenRes == "success") {
    // 刷新token
    if (isRefreshToken === 1) {
      error.response.config.headers.accessToken = getCookie(
        "accessToken"
      );
      return service(error.response.config);
    } else {
      router.go(0);
    }
  } else {
    removeStore("userInfoManager");
    removeCookie("accessToken");
    removeCookie("refreshToken");
    router.push("/login");
  }
}

// 防抖闭包来一波
function getTokenDebounce() {
  let lock = false;
  let success = false;
  return () => {
    if (!lock) {
      lock = true;
      let oldRefreshToken = getCookie("refreshToken");
      handleRefreshToken(oldRefreshToken)
        .then(res => {
          if (res.success) {
            let { accessToken, refreshToken } = res.result;
            setCookie("accessToken", accessToken);
            setCookie("refreshToken", refreshToken);
            success = true;
          } else {
            router.push("/login");
          }
        })
        .finally(() => {
          lock = false;
        });
    }
    return new Promise((resolve) => {
      // 一直看lock,直到请求失败或者成功
      const timer = setInterval(() => {
        if (!lock) {
          clearInterval(timer);
          resolve(success ? "success" : "fail");
        }
      }, 500); // 轮询时间间隔
    });
  };
}

export const getRequest = (url, params) => {
  let accessToken = getCookie("accessToken");
  return service({
    method: "get",
    url: `${url}`,
    params: params,
    headers: {
      accessToken: accessToken
    }
  });
};

export const postRequest = (url, params, headers, timeout = 30 * 1000) => {
  let accessToken = getCookie("accessToken");
  return service({
    method: "post",
    url: `${url}`,
    timeout: timeout,
    data: params,
    transformRequest: headers
      ? undefined
      : [
          function(data) {
            let ret = "";
            for (let it in data) {
              ret +=
                encodeURIComponent(it) +
                "=" +
                encodeURIComponent(data[it]) +
                "&";
            }
            ret = ret.substring(0, ret.length - 1);
            return ret;
          }
        ],
    headers: {
      "Content-Type": "application/x-www-form-urlencoded",
      accessToken: accessToken,
      ...headers
    }
  });
};

/** 不带form表单不带transformRequest */
export const postRequestWithNoForm = (url, params) => {
  let accessToken = getCookie("accessToken");
  return service({
    method: "post",
    url: `${url}`,
    data: params,

    headers: {
      accessToken: accessToken
    }
  });
};

// export const postRequestWithHeaders = (url, params) => {
//   let accessToken = getCookie("accessToken");
//   return axios({
//     method: "post",
//     url: `${url}`,
//     data: params,

//     headers: {
//       accessToken: accessToken,
//       "Content-Type": "application/x-www-form-urlencoded"
//     }
//   });
// };

export const putRequest = (url, params, headers, timeout = 30 * 1000) => {
  let accessToken = getCookie("accessToken");
  return service({
    method: "put",
    url: `${url}`,
    data: params,
    timeout: timeout,
    transformRequest: headers
      ? undefined
      : [
          function(data) {
            let ret = "";
            for (let it in data) {
              ret +=
                encodeURIComponent(it) +
                "=" +
                encodeURIComponent(data[it]) +
                "&";
            }
            ret = ret.substring(0, ret.length - 1);
            return ret;
          }
        ],
    headers: {
      "Content-Type": "application/x-www-form-urlencoded",
      accessToken: accessToken,
      ...headers
    }
  });
};

export const putRequestWithNoForm = (url, params, format = 'form-data') => {
  let ContentType = format == 'form-data'? 'multipart/form-data' : 'application/json';
  let accessToken = getCookie("accessToken");
  return service({
    method: "put",
    url: `${url}`,
    data: params,
    headers: {
      accessToken: accessToken,
      'Content-Type': ContentType
    }
  });
};

export const deleteRequest = (url, params) => {
  let accessToken = getCookie("accessToken");
  return service({
    method: "delete",
    url: `${url}`,
    params: params,
    headers: {
      accessToken: accessToken
    }
  });
};

export const importRequest = (url, params) => {
  let accessToken = getCookie("accessToken");
  return service({
    method: "post",
    url: `${url}`,
    data: params,
    headers: {
      accessToken: accessToken
    }
  });
};

export const uploadFileRequest = (url, params) => {
  let accessToken = getCookie("accessToken");
  return service({
    method: "post",
    url: `${url}`,
    data: params,
    headers: {
      accessToken: accessToken,
      'Content-Type': 'multipart/form-data'
    }
  });
};

/**
 * 无需token验证的请求 避免旧token过期导致请求失败
 * @param {*} url
 * @param {*} params
 */
export const getRequestWithNoToken = (url, params) => {
  return service({
    method: "get",
    url: `${url}`,
    params: params
  });
};

/**
 * 无需token验证的请求 避免旧token过期导致请求失败
 * @param {*} url
 * @param {*} params
 */
export const postRequestWithNoToken = (url, params) => {
  return service({
    method: "post",
    url: `${url}`,
    params: params
  });
};

/**
 * 无需token验证的请求 避免旧token过期导致请求失败
 * @param {*} url
 * @param {*} params
 */
export const postRequestWithNoTokenData = (url, params) => {
  return service({
    method: "post",
    url: `${url}`,
    headers: {
      "Content-Type": "application/x-www-form-urlencoded"
    },
    data: params
  });
};